//
//  NetRequest.m
//  KidReading
//
//  Created by telen on 14/12/4.
//  Copyright (c) 2014年 刘赞黄Telen. All rights reserved.
//

#import "NetRequest.h"
#import <sys/utsname.h>
#import "ConstDefine.h"
#if __Debug_CloseAES == 0
#define __FileNetKeepSuccess @"TLNetKeepSuccess.telen"
#else
#define __FileNetKeepSuccess @"TLNetKeepSuccess.txt"
#endif

typedef enum : NSUInteger {
    NetAskType_nomarl = 1,
    NetAskType_downBooksZip,
    NetAskType_downFile,
} NetAskType;

@implementation NetRequest
@synthesize appVer = appVersion;
@synthesize appBuildVer = appVersionBundle;
@synthesize osVer = os_ver;
@synthesize deviceName_System = deviceName;

static NetRequest* singleNetRequest = nil;

-(NSString*) machineName
{
    struct utsname systemInfo;
    uname(&systemInfo);
    NSString* deviceString = [NSString stringWithCString:systemInfo.machine
                                                encoding:NSUTF8StringEncoding];
    NSString* deviceModel = [[UIDevice currentDevice] model];
    if ([deviceString hasPrefix:deviceModel]) {
        return deviceString;
    }
    return deviceModel;
}

- (instancetype)init
{
    if (self = [super init]) {
        os_ver = [UIDevice currentDevice].systemVersion;
        NSDictionary *infoDic = [[NSBundle mainBundle] infoDictionary];
        appVersionBundle = [infoDic objectForKey:@"CFBundleVersion"];
        appVersion = [infoDic objectForKey:@"CFBundleShortVersionString"];
        deviceName = [self machineName];
#ifdef __SerAPI_Version
        appVersion = __SerAPI_Version;
#endif
        //
        NSString *documentsDirectory = [self getSavePath];
        NSString *SystemSave = [documentsDirectory stringByAppendingPathComponent:__FileNetKeepSuccess];
#if __Debug_CloseAES == 0
        NSData* data = [[NSData alloc] initWithContentsOfFile:SystemSave];
        data = [data AES256DecryptWithKey:__AESKey];//解密
        @try {
            keepSuccessRequestArr = [NSKeyedUnarchiver unarchiveObjectWithData:data];
        }
        @catch (NSException *exception) {
            NSLog(@"%@",exception);
        }
        @finally {
            
        }
#else
        keepSuccessRequestArr = [[NSMutableArray alloc] initWithContentsOfFile:SystemSave];
#endif
    }
    return self;
}

+ (NetRequest *)shareSingle
{
    if (!singleNetRequest) {
        singleNetRequest = [[NetRequest alloc] init];
    }
    return singleNetRequest;
}

- (void)saveNetKeepSuccessCache
{
    NSString *documentsDirectory = [self getSavePath];
    NSString *SystemSave         = [documentsDirectory stringByAppendingPathComponent:__FileNetKeepSuccess];
    
#if __Debug_CloseAES == 0
    NSData* data = [NSKeyedArchiver archivedDataWithRootObject:keepSuccessRequestArr];
    data = [data AES256EncryptWithKey:__AESKey];//加密
    [data writeToFile:SystemSave atomically:YES];
#else
    [keepSuccessRequestArr writeToFile:SystemSave atomically:YES];
#endif
}

- (NSMutableDictionary*)netRequestAddBaseInfo:(NSDictionary*)dict
{
    //添加固定增加信息
    NSMutableDictionary* newDict = [NSMutableDictionary dictionaryWithDictionary:dict];
    [newDict addEntriesFromDictionary:[DataProcessing getSaltInfo]];
    [newDict setObject:[self getUMSuiid] forKey:@"uuid"];
    if ([DataProcessing shareSingle].deviceType == DevicesTypes_iPad) {
        [newDict setObject:@"pad" forKey:@"device_type"];
    }else{
        [newDict setObject:@"phone" forKey:@"device_type"];
    }
    [newDict setObject:@"ios" forKey:@"platform"];
    if(os_ver)[newDict setObject:os_ver forKey:@"os_ver"];
    if(appVersionBundle)[newDict setObject:appVersionBundle forKey:@"app_ver_Bundle"];
    if(appVersion)[newDict setObject:appVersion forKey:@"app_ver"];
    [newDict setObject:[DataProcessing shareSingle].language forKey:@"client_lang"];
    if(deviceName)[newDict setObject:deviceName forKey:@"deviceName"];
    UserInfo* uinfo = [CacheData shareSingle].getUserLoginInfo;
    if(uinfo.uid)[newDict setObject:@(uinfo.uid).description forKey:@"userId"];
    if(uinfo.catoken)[newDict setObject:uinfo.catoken forKey:@"caToken"];
    if(uinfo.token)[newDict setObject:uinfo.token forKey:@"token"];
    if(uinfo.country_code)[newDict setObject:uinfo.country_code forKey:@"country_code"];
    return newDict;
}

// getUMSuiid
- (NSString*)getUMSuiid
{
    NSString* udid = [self getIDFV];
    if ([udid hasPrefix:@"idfv_"]) {
        return udid;
    }else {
        return [NSString stringWithFormat:@"idfv_%@",udid];
    }
}

#define __IDFVServer  @"com.wawayaya.reader.uuid"

- (NSString *)getIDFV
{
    NSString * udidInKeyChain = [WY_SFHFKeychainUtils getPasswordForUsername:@"UMSAgentUDID" andServiceName:@"UMSAgent" error:nil];
    if (!udidInKeyChain) {
        udidInKeyChain = [self load:__IDFVServer];
    }
    if(udidInKeyChain && ![udidInKeyChain isEqualToString:@""])
    {
        if (![udidInKeyChain hasPrefix:@"idfv_"]) {
            udidInKeyChain = [NSString stringWithFormat:@"idfv_%@",udidInKeyChain];
        }
        return udidInKeyChain;
    }
    else
    {
        NSString *idfa = [[[UIDevice currentDevice] identifierForVendor] UUIDString];//idfv
        //NSString *idfa = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
        if (idfa) {
            idfa = [NSString stringWithFormat:@"idfv_%@",idfa];
        }
        if(idfa && ![idfa isEqualToString:@""])
        {
            [WY_SFHFKeychainUtils storeUsername:@"UMSAgentUDID" andPassword:idfa forServiceName:@"UMSAgent" updateExisting:NO error:nil];
            [self save:__IDFVServer data:idfa];
            return idfa;
        }
        else
        {
            NSString *openUDID = @"idfv_0000-0000-0000-0000";
            return openUDID;
        }
    }
}

- (BOOL)isOK_netRequestBaseInfo:(NSDictionary*)dict isLogin:(BOOL)yn
{
    NSString* str = dict[@"token"];
    NSNumber* num = dict[@"userId"];
    if (!yn && (!str || str.length <= 0)) {
        return NO;
    }
    if (!num || num.intValue == 0) {
        return NO;
    }
    return YES;
}

- (NSString*)netFullUrl_Get:(NSString*)urlstr fromDict:(NSDictionary*)dict
{
    return [[self class] netFullUrl_Get:urlstr fromDict:dict];
}
+ (NSString*)netFullUrl_Get:(NSString*)urlstr fromDict:(NSDictionary*)dict
{
    if (![urlstr hasPrefix:@"http"]) {
        return nil;
    }
    if (!dict) {
        return urlstr;
    }
    NSArray* arr = [urlstr componentsSeparatedByString:@"?"];
    if (arr.count > 0) {
        urlstr = @"";
        if (arr.count >= 2) {
            urlstr = arr[1];
        }
        NSMutableArray *oreadyKeys = [NSMutableArray array];
        if(urlstr.length){
           NSArray* paraArr = [urlstr componentsSeparatedByString:@"&"];
            for (NSString *paraStr in paraArr) {
                if (paraStr.length) {
                    NSArray* itemParaArr = [paraStr componentsSeparatedByString:@"="];
                    if (itemParaArr.count > 1) {
                        [oreadyKeys addObject:itemParaArr[0]];
                    }
                }
            }
        }
        
        NSArray* keys = [dict allKeys];
        for (NSString* key in keys) {
            if(key.length==0)continue;
            BOOL isTheSame = NO;
            for (NSString *oKeystr in oreadyKeys) {
                if ([key isEqualToString:oKeystr]) {
                    isTheSame = YES;
                    break;
                }
            }
            if (isTheSame)continue;
            if (urlstr.length > 0) {
                urlstr = [urlstr stringByAppendingString:@"&"];
            }
            urlstr = [urlstr stringByAppendingString:key.URLEncodedString_2];
            urlstr = [urlstr stringByAppendingString:@"="];
            NSString* value = [NSString stringWithFormat:@"%@",[dict objectForKey:key]];
            urlstr = [urlstr stringByAppendingString:value.URLEncodedString_2];
        }
        urlstr = [NSString stringWithFormat:@"%@?%@",arr[0],urlstr];
    }
    return urlstr;
}

- (NSString*)netPostString_fromDict:(NSDictionary*)dict
{
    return[[self class] netPostString_fromDict:dict];
}
+ (NSString*)netPostString_fromDict:(NSDictionary*)dict
{
    NSString* urlstr = @"";
    NSArray* keys = [dict allKeys];
    for (NSString* key in keys) {
        if(key.length==0)continue;
        urlstr = [urlstr stringByAppendingString:key.URLEncodedString_2];
        urlstr = [urlstr stringByAppendingString:@"="];
        NSString* value = [NSString stringWithFormat:@"%@",[dict objectForKey:key]];
        urlstr = [urlstr stringByAppendingString:value.URLEncodedString_2];
        urlstr = [urlstr stringByAppendingString:@"&"];
    }
    return urlstr;
}

- (NSDictionary*)netPostString_fromGetStr:(NSString*)refStr
{
    return [[self class] netPostString_fromGetStr:refStr];
}
+ (NSDictionary*)netPostString_fromGetStr:(NSString*)refStr;
{
    if (refStr) {
        NSMutableDictionary* mdic = [NSMutableDictionary new];
        NSArray* arr = [refStr componentsSeparatedByString:@"&"];
        for (int i=0; i<arr.count; i++) {
            NSString* str = arr[i];
            NSArray* kvs = [str componentsSeparatedByString:@"="];
            if (kvs.count == 2) {
                [mdic setObject:kvs[1] forKey:kvs[0]];
            }else if(kvs.count > 2 && [kvs[1] hasPrefix:@"http"]){
                NSString* val = @"";
                NSMutableArray* mkvs = [NSMutableArray arrayWithArray:kvs];
                [mkvs removeObjectAtIndex:0];
                NSMutableArray* marr = [NSMutableArray arrayWithArray:arr];
                for (int j=0; j<=i; j++) {
                    [marr removeObjectAtIndex:0];
                }
                val = [mkvs componentsJoinedByString:@"="];
                [marr insertObject:val atIndex:0];
                val = [marr componentsJoinedByString:@"&"];
                [mdic setObject:val forKey:kvs[0]];
                break;
            }else{
                break;
            }
        }
        return mdic;
    }
    return nil;
}

- (NSString*)getSavePath
{
    NSArray  *paths              = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask,YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    return documentsDirectory;
}

- (void)askNet:(NSString *)port refsDict:(NSDictionary *)dict delegate:(id<NetRequestDelegate>)delegate withThroughDict:(NSDictionary *)throughDict
{
    [self askNet:port refsDict:dict delegate:delegate withThroughDict:throughDict keepSuccess:NO];
}

- (void)askNet:(NSString *)port refsDict:(NSDictionary *)dict delegate:(id<NetRequestDelegate>)delegate withThroughDict:(NSDictionary *)throughDict keepSuccess:(BOOL)iskeep
{
    [self askNet:port andBaseUrl:__URL_Base_ refsDict:dict delegate:delegate withThroughDict:throughDict keepSuccess:iskeep];
}

- (void)askNet:(NSString *)port andBaseUrl:(NSString *)baseUrl refsDict:(NSDictionary *)dict delegate:(id<NetRequestDelegate>)delegate withThroughDict:(NSDictionary *)throughDict
{
    [self askNet:port andBaseUrl:baseUrl refsDict:dict delegate:delegate withThroughDict:throughDict keepSuccess:NO];
}

- (void)askNet:(NSString *)port andBaseUrl:(NSString *)baseUrl refsDict:(NSDictionary *)dict delegate:(id<NetRequestDelegate>)delegate withThroughDict:(NSDictionary *)throughDict keepSuccess:(BOOL)iskeep
 {
     //保持访问成功管理
     NSDictionary* keepRequestDict = [NSDictionary dictionaryWithObjectsAndKeys:port,@"port",baseUrl,@"baseUrl",dict,@"refdict", nil];
     if (iskeep) {
         [keepSuccessRequestArr addObject:keepRequestDict];
         [self saveNetKeepSuccessCache];
     }
     //
     NSString* urlstr = [NSMutableString stringWithString:baseUrl];
     urlstr = [urlstr stringByAppendingString:port];
     NSURL* url = [NSURL URLWithString:urlstr];
     NSMutableData* receivedData = [[NSMutableData alloc] initWithCapacity:0];
     NSMutableDictionary* userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:keepRequestDict,@"keepRequestDict",receivedData,@"receivedData",delegate,@"delegate",nil];
     if (throughDict) {
         [userInfo setObject:throughDict forKey:__throughDict__];
     }
     //添加固定增加信息
     dict = [self netRequestAddBaseInfo:dict];
    
#if __Debug_Net_Get
#define __Using_RequestType 1 //1使用Get
#else
#define __Using_RequestType 2 //1使用Get 2使用Post 3使用Post URLEncoded
#endif
#if __Using_RequestType == 3
    ASIFormDataRequest* asiRequest = [ASIFormDataRequest requestWithURL:url];
    NSArray* keys = [dict allKeys];
    for (NSString* key in keys) {
        if(key.length==0)continue;
        NSString* value = [NSString stringWithFormat:@"%@",[dict objectForKey:key]];
        value = [value URLEncodedString];
        [asiRequest setPostValue:value forKey:key];
    }
    [asiRequest setRequestMethod:@"POST"];
    [asiRequest buildPostBody];
    [asiRequest setUserInfo:userInfo];
    [asiRequest setTag:NetAskType_nomarl];
    [asiRequest setTimeOutSeconds:__NetTimeOut_];
    [asiRequest setDelegate:self];
    [asiRequest startAsynchronous];
#elif  __Using_RequestType == 2
    JRASIFormDataRequest* asiRequest = [JRASIFormDataRequest requestWithURL:url];
    NSArray* keys = [dict allKeys];
    for (NSString* key in keys) {
        if(key.length==0)continue;
        [asiRequest setPostValue:[dict objectForKey:key] forKey:key];
    }
    [asiRequest setRequestMethod:@"POST"];
    [asiRequest buildPostBody];
    [asiRequest setUserInfo:userInfo];
    [asiRequest setTag:NetAskType_nomarl];
    [asiRequest setTimeOutSeconds:__NetTimeOut_];
    [asiRequest setDelegate:self];
    [asiRequest startAsynchronous];
#elif  __Using_RequestType == 1
     if (!([urlstr componentsSeparatedByString:@"?"].count > 1)) {
         urlstr = [urlstr stringByAppendingString:@"?"];
     }
    NSArray* keys = [dict allKeys];
    for (NSString* key in keys) {
        if(key.length==0)continue;
        urlstr = [urlstr stringByAppendingString:key];
        urlstr = [urlstr stringByAppendingString:@"="];
        NSString* value = [NSString stringWithFormat:@"%@",[dict objectForKey:key]];
        urlstr = [urlstr stringByAppendingString:value];
        urlstr = [urlstr stringByAppendingString:@"&"];
    }
    urlstr = [urlstr URLEncodedString];
    url = [NSURL URLWithString:urlstr];
    ASIHTTPRequest* asiRequest = [ASIHTTPRequest requestWithURL:url];
    [asiRequest setUserInfo:userInfo];
    [asiRequest setTag:NetAskType_nomarl];
    [asiRequest setTimeOutSeconds:__NetTimeOut_];
    [asiRequest setDelegate:self];
    [asiRequest startAsynchronous];
#endif
    
#if __Debug_Net
    NSLog(@"url:%@",url);
    NSLog(@"dict:%@",dict);
#endif
}

#pragma mark- delegate


- (void)request:(JRASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders
{
    NSMutableDictionary* userInfo = (NSMutableDictionary*)[request userInfo];
    if([responseHeaders objectForKey:@"Content-Length"] )[userInfo setObject:[responseHeaders objectForKey:@"Content-Length"] forKey:@"Content-Length"];
    else
    {
//        NSAssert(0, @"[responseHeaders objectForKey:@\"Content-Length\"] == nil");
#if __Debug_Net
        NSLog(@"[responseHeaders objectForKey:@\"Content-Length\"] == nil");
        NSLog(@"%@",request.url);
#endif
    }
#if __Debug_Net
    NSLog(@"%@",responseHeaders);
#endif
}


- (void)request:(JRASIHTTPRequest *)request didReceiveData:(NSData *)data
{
    NSMutableData* receivedData = [[request userInfo] objectForKey:@"receivedData"];
    if (receivedData) {
        [receivedData appendData:data];
        //---
        id<NetRequestDelegate> delegate = [[request userInfo] objectForKey:@"delegate"];
        NSNumber* AllLength = [[request userInfo] objectForKey:@"Content-Length"];
        if (AllLength) {
            NSInteger length = receivedData.length;
            CGFloat p = length*1.0/([AllLength integerValue]);
            if (delegate && [delegate respondsToSelector:@selector(netRequestPerReceiveData:)]) {
                [delegate netRequestPerReceiveData:p];
            }
#if __Debug_Net
        NSLog(@"%@ receivedData : %.2f",[delegate class],p);
#endif
        }
    }else{
        NSLog(@"receivedData == nil");
    }
    
#if __Debug_Net
//    NSLog(@"%s",data.bytes);
#endif
}

- (void)requestFinished:(JRASIHTTPRequest *)request
{
    //NSLog(@"request------URL: %@",[request url]);
    NSData* responseData=[request responseData];
    if (!responseData || responseData.length <= 0) {
        responseData = [[request userInfo] objectForKey:@"receivedData"];
    }
#if __Debug_Net
    NSString* str2 = [request responseStatusMessage];
    NSString* str1 = [request responseString];
    NSLog(@"requestStatus:%@  requestMsg:%@",str2,str1);
    NSLog(@"URL: %@",[request url]);
#endif
    
    NSError* error=nil;
    NSAssert(responseData != nil, @"没有到服务器返回的数据");

    NSDictionary* dicMessage=[NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&error];

#if __Debug_Net || __Debug_Net_Error
    if (dicMessage == nil) {
        NSLog(@"errorURL: %@",[request url]);
        NSLog(@"size:%@ 完整data: %s",@(responseData.length),responseData.bytes);
        //
        AppDelegate* appdelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
        PopWebView* webview = [[PopWebView alloc] initWithFrame:appdelegate.window.bounds];
        [webview.webview loadData:responseData MIMEType:@"text/html" textEncodingName:@"UTF-8" baseURL:request.url];
        webview.labelUrl.text = [request.url absoluteString];
        [appdelegate.window addSubview:webview];
        [webview autoLayOut];
    }
#endif
    
    if (dicMessage) {
        id<NetRequestDelegate> delegate = [[request userInfo] objectForKey:@"delegate"];
        NSDictionary* throughDict = [[request userInfo] objectForKey:__throughDict__];
        NSDictionary* dic = [NSDictionary dictionaryWithObjectsAndKeys:dicMessage,__NetBack__,throughDict,__throughDict__, nil];
#if __Debug_Net
        NSLog(@"%@",dic);
#endif
        NSNumber* success = nil;
        if ([dicMessage isKindOfClass:[NSDictionary class]]) {
            success = [dicMessage objectForKey:@"success"];
        }
        if (success && [success isEqualToNumber:@(0)]) {
            if (delegate && [delegate respondsToSelector:@selector(netRequestFailed:)]) {
                [delegate netRequestFailed:dic];
            }
            NSString* msg = [[dicMessage objectForKey:@"message"] description];
            if(msg)[UIAlertView showAluertMessage:msg title:nil sureBtn:NSLocalizedString(@"sure", "")];
        }else{
            if (delegate && [delegate respondsToSelector:@selector(netRequestFinished:)]) {
                [delegate netRequestFinished:dic];
            }
        }
    }else{
        id<NetRequestDelegate> delegate = [[request userInfo] objectForKey:@"delegate"];
        NSDictionary* throughDict = [[request userInfo] objectForKey:__throughDict__];
        NSDictionary* dic = [NSDictionary dictionaryWithObjectsAndKeys:throughDict,__throughDict__, nil];
        if (delegate && [delegate respondsToSelector:@selector(netRequestFinished:)]) {
            [delegate netRequestFailed:dic];
        }
    }
    
    //保持访问成功管理
    NSDictionary* keepRequestDict = [request.userInfo objectForKey:@"keepRequestDict"];
    for (NSDictionary* keepDict in keepSuccessRequestArr) {
        if (keepRequestDict == keepDict) {
            [keepSuccessRequestArr removeObject:keepDict];
            [self saveNetKeepSuccessCache];
            break;
        }
    }
    keepRequestDict = [keepSuccessRequestArr firstObject];
    if (keepRequestDict) {
        NSString* port = [keepRequestDict objectForKey:@"port"];
        NSString* baseUrl = [keepRequestDict objectForKey:@"baseUrl"];
        NSDictionary* refdict = [keepRequestDict objectForKey:@"refdict"];
        [self askNet:port andBaseUrl:baseUrl refsDict:refdict delegate:nil withThroughDict:nil keepSuccess:NO];
    }
}

- (void)requestFailed:(JRASIHTTPRequest *)request
{
#if __Debug_Net || __Debug_Net_Error
    NSString* str1 = [request responseString];
    NSString* str2 = [request responseStatusMessage];
    NSLog(@"requestStatus:%@  requestMsg:%@",str2,str1);
    NSURL* url = [request url];
    NSLog(@"requestFailed:errorURL: %@",url);
    NSLog(@"error: %@",request.error);
#endif
    id<NetRequestDelegate> delegate = [[request userInfo] objectForKey:@"delegate"];
    NSDictionary* throughDict = [[request userInfo] objectForKey:__throughDict__];
    if (delegate && [delegate respondsToSelector:@selector(netRequestFailed:)]) {
        NSDictionary* dic = [NSDictionary dictionaryWithObjectsAndKeys:throughDict,__throughDict__, nil];
        [delegate netRequestFailed:dic];
    }
    //
    [[WaitingShow shareSingleShow] showString:NSLocalizedString(@"netRequestFail", "") andAutoHide:YES];
}

-(NSDictionary*)sendSynchronous:(NSString*)URLString ref:(NSDictionary*)dict data:(NSData*)data
{
    //NSURL *url = [NSURL URLWithString:URLString];
    //添加固定增加信息

    NSString* urlstr = [self netFullUrl_Get:URLString fromDict:dict];

    NSData* requestData = data;
    
    NSString* contentType=@"application/x-www-form-urlencoded";
    
    NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlstr]];
    [request setHTTPMethod: @"POST"];
    [request addValue:contentType forHTTPHeaderField:@"Content-Type"];
    NSString *len = [NSString stringWithFormat:@"%@",@([requestData length])];
    [request setValue:len forHTTPHeaderField:@"Content-Length"];
    [request setHTTPBody: requestData];
    
    NSError        *responseError = nil;
    NSURLResponse  *response = nil;
    
#if __Debug_Net
    NSLog(@"url:%@",urlstr);
    NSLog(@"dict:%@",dict);
    NSLog(@"Data:%@",requestData);
#endif
    
    NSData *returnData = [ NSURLConnection sendSynchronousRequest: request returningResponse: &response error: &responseError ];
    if (response == nil) {
        if (responseError != nil) {
            NSLog(@"Connection to server failed.");
            NSLog(@"%@",responseError);
        }
        return [NSDictionary dictionaryWithObjectsAndKeys:@(0),@"success",@"network connection error",@"msg", nil];
    }
    else {
        NSData* responseData = returnData;
        NSDictionary* retDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:nil];
#if __Debug_Net || __Debug_Net_Error
        if (retDictionary == nil) {
            if(returnData)[PopWebView popWebViewWithData:returnData withURL:URLString];
            if(responseError){
                NSString* str = [responseError description];
                returnData = [NSData dataWithBytes:str.UTF8String length:str.length];
                [PopWebView popWebViewWithData:returnData withURL:URLString];
            }
        }
#endif
#if __Debug_Net
        NSLog(@"Ret Buy %@",retDictionary);
#endif
        return retDictionary;
    }
}

#pragma mark- AFN

- (void)askNet:(NSString*)port andBaseUrl:(NSString*)baseUrl parameters:(NSDictionary*)dict success:(void (^)(NSDictionary* retDict))success failure:(void (^)(NSError *error))failure;
{
    NSString *urlPath = [DataProcessing full_BaseUrl:baseUrl url:port];
    //1.1创建一个AFN管理对象
    JRAFHTTPSessionManager *manager = [JRAFHTTPSessionManager manager];
    //1.2告诉manager只下载原始数据, 不要解析数据(一定要写)
    //AFN即可以下载网络数据, 又可以解析json数据,如果不写下面的  自动就解析json
    manager.responseSerializer = [JRAFHTTPResponseSerializer serializer];
    //1.3使用GET下载数据
    NSDictionary *params = [self netRequestAddBaseInfo:dict];
#if __Debug_Net
    NSLog(@"URL:%@",urlPath);
    NSLog(@"Ref:%@",params);
    NSDate* begin = [NSDate date];
#endif
    //ser3 开启安全访问过滤
    BOOL yn = [port hasSuffix:@"/login"];
    BOOL refOK = [self isOK_netRequestBaseInfo:params isLogin:yn];
    if (refOK == NO) {
        if(failure)failure(nil);
        NSLog(@"Request Ref miss 无效的网络请求");
        return;
    }
    NSURLSessionTask* task_post =[manager POST:urlPath parameters:params success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
        for (NSURLSessionTask* tsk in afnet_ing_Arr) {
            if (tsk ==  task) {
                [afnet_ing_Arr removeObject:tsk];
                break;
            }
        }
#if __Debug_Net
        NSTimeInterval time = [begin timeIntervalSinceNow];
        NSLog(@"网络耗费时间:%lf (%@)",time,urlPath);
#endif
        NSData *responseData = [NSData dataWithData:responseObject];
        NSDictionary *dicMessage = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:nil];

#if __Debug_Net || __Debug_Net_Error
             if (dicMessage == nil) {
                 NSLog(@"errorURL: %@",task.currentRequest);
                 NSLog(@"size:%@ 完整data: %s",@(responseData.length),responseData.bytes);
                 //
                 AppDelegate* appdelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
                 PopWebView* webview = [[PopWebView alloc] initWithFrame:appdelegate.window.bounds];
                 [webview.webview loadData:responseData MIMEType:@"text/html" textEncodingName:@"UTF-8" baseURL:task.originalRequest.URL];
                 webview.labelUrl.text = [task.originalRequest.URL absoluteString];
                 [appdelegate.window addSubview:webview];
                 [webview autoLayOut];
                 failure(nil);
             }
#endif
             if (dicMessage) {
                 success(dicMessage);
#if __Debug_Net
                 NSTimeInterval time = [begin timeIntervalSinceNow];
                 NSLog(@"累计耗费时间:%lf (%@)",time,urlPath);
                 NSLog(@"%@",dicMessage);
#endif
             }
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        for (NSURLSessionTask* tsk in afnet_ing_Arr) {
            if (tsk ==  task) {
                [afnet_ing_Arr removeObject:tsk];
                break;
            }
        }
        failure(error);
#if __Debug_Net || __Debug_Net_Error
        NSLog(@"网络get错误 is %@",error);//-1009 取消 -1004 无网络
        if (error != nil && error.code != -1009 && error.code != -1004) {
            NSData* responseData = [error.description dataUsingEncoding:NSUTF8StringEncoding];
            AppDelegate* appdelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
            PopWebView* webview = [[PopWebView alloc] initWithFrame:appdelegate.window.bounds];
            [webview.webview loadData:responseData MIMEType:@"text/html" textEncodingName:@"UTF-8" baseURL:task.originalRequest.URL];
            webview.labelUrl.text = [task.originalRequest.URL absoluteString];
            [appdelegate.window addSubview:webview];
            [webview autoLayOut];
            failure(nil);
        }
#endif
        
    }];
    //
    if (!afnet_ing_Arr) {
        afnet_ing_Arr = [NSMutableArray new];
    }
    [afnet_ing_Arr addObject:task_post];
}

#ifndef WHY_PJ
- (void)webViewAskNet:(NSString *)port andBaseUrl:(NSString *)baseUrl parameters:(NSDictionary *)parameters success:(void (^)(NSData* retData))success failure:(void (^)(NSError *error))failure{
    NSMutableArray* afnet_Data_Arr = nil;
    
    NSString *urlPath = [DataProcessing full_BaseUrl:baseUrl url:port];
    //1.1创建一个AFN管理对象
    JRAFHTTPSessionManager *manager = [JRAFHTTPSessionManager manager];
    //1.2告诉manager只下载原始数据, 不要解析数据(一定要写)
    //AFN即可以下载网络数据, 又可以解析json数据,如果不写下面的  自动就解析json
    manager.responseSerializer = [JRAFHTTPResponseSerializer serializer];
    //1.3使用GET下载数据
    NSDictionary *params = [self netRequestAddBaseInfo:parameters];
#if __Debug_Net
    NSLog(@"URL:%@",urlPath);
    NSLog(@"Ref:%@",params);
    NSDate* begin = [NSDate date];
#endif
    //ser3 开启安全访问过滤
    BOOL yn = [port hasSuffix:@"/login"];
    BOOL refOK = [self isOK_netRequestBaseInfo:params isLogin:yn];
    if (refOK == NO) {
        if(failure)failure(nil);
        NSLog(@"Request Ref miss 无效的网络请求");
        return;
    }
    NSURLSessionTask* task_post =[manager POST:urlPath parameters:params success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
        for (NSURLSessionTask* tsk in afnet_Data_Arr) {
            if (tsk ==  task) {
                [afnet_Data_Arr removeObject:tsk];
                break;
            }
        }
#if __Debug_Net
        NSTimeInterval time = [begin timeIntervalSinceNow];
        NSLog(@"网络耗费时间:%lf (%@)",time,urlPath);
#endif
        NSData *responseData = [NSData dataWithData:responseObject];
        NSDictionary *dicMessage = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:nil];
        if (dicMessage) {
            //json 解析
           // NSDictionary* dict = dicMessage[@"retinfo"];
            NSString* msg = dicMessage[@"msg"];
            NSInteger flag = [dicMessage[@"flag"] integerValue];
            if (msg) {
                if (flag == 1001) {//token 过期
                    NSLog(@"token out: /telen%@",port);
                    //[[DBHelper shareInstance] showTokenOutMsg:msg];
                    [NSObject msgToClassName:@"DBHelper" menthed:@"showTokenOutMsg:" refs:@[msg] needReturnValue:NO];
                    return ;
                }
            }
        }
        if (responseData) {
            if (!dicMessage) {
               success(responseData);
            }else {
                success(nil);
            }
#if __Debug_Net
            NSTimeInterval time = [begin timeIntervalSinceNow];
            NSLog(@"累计耗费时间:%lf (%@)",time,urlPath);
            NSLog(@"%@",dicMessage);
#endif
        }
        
  
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        for (NSURLSessionTask* tsk in afnet_Data_Arr) {
            if (tsk ==  task) {
                [afnet_Data_Arr removeObject:tsk];
                break;
            }
        }
        failure(error);
#if __Debug_Net || __Debug_Net_Error
        NSLog(@"网络get错误 is %@",error);
#endif
        
    }];
    //
    if (!afnet_Data_Arr) {
        afnet_Data_Arr = [NSMutableArray new];
    }
    [afnet_Data_Arr addObject:task_post];
}
#endif

- (void)cancel_all_afnet_Request
{
    for (NSURLSessionTask* tsk in afnet_ing_Arr) {
        [tsk cancel];
    }
}

#pragma mark KeyChain
- (NSMutableDictionary *)getKeychainQuery:(NSString *)service {
    return [NSMutableDictionary dictionaryWithObjectsAndKeys:
            (id)kSecClassGenericPassword,(id)kSecClass,
            service, (id)kSecAttrService,
            service, (id)kSecAttrAccount,
            (id)kSecAttrAccessibleAfterFirstUnlock,(id)kSecAttrAccessible,
            nil];
}

- (void)save:(NSString *)service data:(id)data {
    //Get search dictionary
    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
    //Delete old item before add new item
    SecItemDelete((CFDictionaryRef)keychainQuery);
    //Add new object to search dictionary(Attention:the data format)
    [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData];
    //Add item to keychain with the search dictionary
    SecItemAdd((CFDictionaryRef)keychainQuery, NULL);
}

- (id)load:(NSString *)service {
    id ret = nil;
    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
    //Configure the search setting
    //Since in our simple case we are expecting only a single attribute to be returned (the password) we can set the attribute kSecReturnData to kCFBooleanTrue
    [keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
    [keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
    CFDataRef keyData = NULL;
    if (SecItemCopyMatching((CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {
        @try {
            ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData];
        } @catch (NSException *e) {
            NSLog(@"Unarchive of %@ failed: %@", service, e);
        } @finally {
        }
    }
    if (keyData)
        CFRelease(keyData);
    return ret;
}

@end
